package com.jgp.sys.service;

import com.jgp.common.pojo.LabelValue;
import com.jgp.common.pojo.TreeBean;
import com.jgp.sys.model.Attribute;
import com.jgp.sys.model.AttributeType;
import com.jgp.sys.model.FunctionType;
import com.jgp.sys.query.Operator;
import com.jgp.sys.query.OrderList;
import com.jgp.sys.query.QueryFilterList;
import com.jgp.sys.repository.AttributesRepository;
import com.jgp.sys.ui.Pager;
import com.jgp.sys.utils.TreeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2019-11-02
 */
@Service
@CacheConfig(cacheNames = "ATTR_SERVICE")
public class AttributeService {
    
    @Autowired
    private AttributesRepository repository;
    
    /**
     * 创建/更新分组
     *
     * @param attr
     */
    @Transactional
    public void saveGroup(Attribute attr) {
        attr.setType(AttributeType.GROUP);
        attr.setFuncType(FunctionType.NONE);
        repository.createOrUpdate(attr);
    }
    
    /**
     * 创建/更新列表
     *
     * @param attr
     */
    @Transactional
    public void saveList(Attribute attr) {
        attr.setType(AttributeType.ACTIVE_GROUP);
        attr.setFuncType(FunctionType.LIST);
        attr.setActiveKey(attr.getValue());
        repository.createOrUpdate(attr);
    }
    
    /**
     * 创建/更新列表项
     *
     * @param attr
     */
    @Transactional
    @CacheEvict(key = "'LIST:'+#attr.activeKey")
    public void saveListItem(Attribute attr) {
        Attribute parent = queryOne(attr.getParentId());
        attr.setType(AttributeType.ITEM);
        attr.setFuncType(FunctionType.LIST);
        attr.setActiveKey(parent.getValue());
        repository.createOrUpdate(attr);
    }
    
    public List<TreeBean> queryGroupTree() {
        List<Attribute> attrs = query(null, null, null, null, AttributeType.GROUP, null, null);
        return TreeUtil.createTree(attrs);
    }
    
    public Attribute queryListGroup(String activeKey) {
        QueryFilterList filters = new QueryFilterList();
        filters.addFilter("funcType", Operator.eq, FunctionType.LIST);
        filters.addFilter("type", Operator.eq, AttributeType.ACTIVE_GROUP);
        filters.addFilter("activeKey", Operator.eq, activeKey);
        filters.addFilter("value", Operator.eq, activeKey);
        return repository.readOne(filters);
    }
    
    public List<Attribute> queryListItem(Long parentId, String name, String code, Pager pager) {
        return query(parentId, null, name, code, AttributeType.ACTIVE_GROUP, FunctionType.LIST, pager);
    }
    
    public List<Attribute> queryListItem(String activeKey, String name, String code, Pager pager) {
        return query(null, activeKey, name, code, AttributeType.ITEM, FunctionType.LIST, pager);
    }
    
    public List<Attribute> query(Long parentId, String activeKey, String name, String code, AttributeType type, FunctionType funcType, Pager pager) {
        QueryFilterList filters = filters(parentId, activeKey, name, code, type, funcType);
        OrderList orders = new OrderList();
        orders.addOrder("sort", "ASC");
        return repository.read(filters, orders, pager);
    }
    
    public Attribute queryOne(Long id) {
        return repository.read(id);
    }
    
    /**
     * 根据activeKey 查询列表数据
     *
     * @param activeKey
     * @return 返回 LabelValue 集合
     */
    @Cacheable(key = "'LIST:'+#activeKey")
    public List<LabelValue> queryLabelValuesByActiveKey(String activeKey) {
        List<Attribute> attrs = queryListItem(activeKey, null, null, null);
        return attrs.stream().map(attr -> {
            LabelValue lv = new LabelValue();
            lv.setLabel(attr.getLabel());
            lv.setValue(attr.getValue());
            Map<String, Object> ext = new HashMap<>();
            ext.put("ext1", attr.getExt1());
            ext.put("ext2", attr.getExt2());
            ext.put("ext3", attr.getExt3());
            lv.setExtMap(ext);
            return lv;
        }).collect(Collectors.toList());
    }
    
    /**
     * 查询多个列表
     *
     * @param activeKeys activeKey集合
     * @return MAP key 为 activeKey value 为对应的列表
     */
    public Map<String, List<LabelValue>> queryLabelValuesByActiveKey(List<String> activeKeys) {
        Map<String, List<LabelValue>> map = new HashMap<>();
        activeKeys.forEach(key -> {
            map.put(key, queryLabelValuesByActiveKey(key));
        });
        return map;
    }
    
    private QueryFilterList filters(Long parentId, String activeKey, String name, String code, AttributeType type, FunctionType funcType) {
        QueryFilterList filters = new QueryFilterList();
        if (StringUtils.isNotBlank(name)) filters.addFilter("label", Operator.like, name);
        if (StringUtils.isNotBlank(code)) filters.addFilter("value", Operator.likeL, code);
        if (Objects.nonNull(parentId) && parentId != -1) filters.addFilter("parentId", Operator.eq, parentId);
        if (Objects.nonNull(funcType)) filters.addFilter("funcType", Operator.eq, funcType);
        if (Objects.nonNull(type)) filters.addFilter("type", Operator.eq, type);
        if (StringUtils.isNotBlank(activeKey)) {
            filters.addFilter("activeKey", Operator.eq, activeKey);
        }
        return filters;
    }
    
    /**
     * 【缓存】
     * 清除缓存
     */
    @CacheEvict(key = "'LIST:*'", allEntries = true)
    public void removeCache() { }
}
